#ifndef MENU_H_
#define MENU_H_

#include <vector>

#include "Window.h"
#include "MenuItem.h"

class Scene;

/**
 * Summary: Menu callback function
 */
typedef void(Scene::*SelectFunction)(int);

/**
 * Summary: Macro for easy callback setting
 */
#define SelectFunctionData(x) this, (SelectFunction)(&x)

/**
 * Summary: A selectable window
 */
class Menu : public Window {
	public:
		/**
		 * Summary: The width of each menu item
		 */
		static const int ITEM_WIDTH = Window::GRID_SIZE * 16;

		/**
		 * Summary: The height of each menu item
		 */
		static const int ITEM_HEIGHT = Window::GRID_SIZE * 3;

		/**
		 * Summary: Returns the Menu at the top of the Menu Stack
		 *
		 * Return: The Menu at the top of the Menu Stack
		 */
		static Menu* getTopMenu();

		/**
		 * Summary: Pushes a menu onto the Menu Stack
		 */
		static void pushMenuStack(Menu* menu);

		/**
		 * Summary: Removes the top level Menu and deletes it
		 */
		static void popMenuStack();

		/**
		 * Summary: Clears the Menu Stack and deletes all Menus in it
		 */
		static void clearMenuStack();

		/**
		 * Summary: Draws all Menus in the Menu Stack
		 */
		static void drawMenuStack();

		/**
		 * Summary: Constructs a Menu
		 *
		 * Arguments:
		 * 	x: The x coordinate of the top-left corner of the window
		 * 	y: The y coordinate of the top-left corner of the window
		 * 	items: The items available in the menu
		 * 	handler: The scene that will execute the callback function
		 *  selectFunction: The function to execute when an item is selected
		 *  numColumns: The number of columns to place the items in
		 *  canExit: Determines whether or not this menu can be exited
		 */
		Menu(int x, int y, vector<MenuItem> items, Scene* handler, SelectFunction selectFunction, int numColumns = 1, bool canExit = true);

		/**
		 * Summary: Destroys a Menu
		 */
		virtual ~Menu();

		/**
		 * Summary: Returns the index of the currently selected item
		 *
		 * Return: The index of the currently selected item
		 */
		int getSelectedIndex() const;

		/**
		 * Summary: Sets the selected index
		 *
		 * Arguments:
		 * 	newIndex: The index of the new item to select
		 */
		void setSelectedIndex(int newIndex);

		/**
		 * Summary: Enables or disables the item at the given index
		 *
		 * Arguments:
		 *  index: The index of the item to enable or disable
		 *  newEnabled: The new enablization status of the item
		 */
		void setItemEnabled(int index, bool newEnabled);

		/**
		 * Summary: Handles an event
		 *
		 * Arguments:
		 * 	event: The event to handle
		 */
		virtual void handleEvent(SDL_Event* event);

	private:
		/**
		 * Summary: The stack of currently opened menus
		 */
		static vector<Menu*> menuStack;

		/**
		 * Summary: The items in the menu
		 */
		vector<MenuItem> items;

		/**
		 * Summary: The scene to execute the callback function
		 */
		Scene* handler;

		/**
		 * Summary: The function to execute when an item is selected
		 */
		SelectFunction selectFunction;

		/**
		 * Summary: The number of columns to put the menu items into
		 */
		int numColumns;

		/**
		 * Summary: Determines whether or not this menu can be exited
		 */
		bool canExit;

		/**
		 * Summary: The index of the currently selected item
		 */
		int selectedIndex;

		/**
		 * Summary: Draws the menu items
		 */
		virtual void drawContent();
};

#endif
